package com.linkhub.oms.data.sync.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.dtflys.forest.http.ForestResponse;
import com.linkhub.oms.common.util.OffSetDateTimeUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.common.util.json.QtFastjsonUtil;
import com.linkhub.oms.data.sync.api.shopify.client.AuthenticationClient;
import com.linkhub.oms.data.sync.api.shopify.client.OrderClient;
import com.linkhub.oms.data.sync.api.shopify.client.ProductClient;
import com.linkhub.oms.data.sync.api.shopify.client.ShopClient;
import com.linkhub.oms.data.sync.api.shopify.domain.request.FulfillmentRequest;
import com.linkhub.oms.data.sync.api.shopify.domain.response.*;
import com.linkhub.oms.data.sync.service.ShopifyApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

import static com.linkhub.oms.data.sync.api.shopify.domain.response.ShopResponse.FIELDS;

/**
 * @Description: ShopifyApiService
 * @Author: echo
 * @Date: 2024/3/21 14:31
 * @Version: 1.0
 */
@Slf4j
@Service
public class ShopifyApiServiceImpl implements ShopifyApiService {

    @Value("${app.client-id}")
    private String clientId;

    @Value("${app.client-secret}")
    private String clientSecret;

    @Resource
    private AuthenticationClient authenticationClient;
    @Resource
    private ShopClient shopClient;
    @Resource
    private ProductClient productClient;
    @Resource
    private OrderClient orderClient;


    @Override
    public OauthAccessTokenResponse getShopAccessToken( String shopUrl, String authorizationCode ) {
        return authenticationClient.getAccessToken(shopUrl, clientId, clientSecret, authorizationCode).getResult();
    }

    @Override
    public ShopResponse getShopInfo( String shopUrl, String accessToken ) {
        return shopClient.shop(accessToken, shopUrl, FIELDS).getResult();
    }

    @Override
    public ShopProductResponse pullShopAllProducts( String shopUrl, String accessToken, String updatedAtMin ) {
        // 获取可拉取的商品数量
        ShopProductResponse response = ShopProductResponse.emptyResponse();
        String pageCondition = updatedAtMin;
        while(true) {

            ShopProductResponse productPage = productClient.listAfterUpdateAtShopProducts(accessToken,
                    shopUrl, ShopProductResponse.FIELDS, pageCondition).getResult();

            if (!productPage.success()) {
                break;
            }
            List<ShopProductResponse.Products> sortedProducts = productPage.getProducts();
            int addBeforeCount = response.count();
            response.addAll(sortedProducts);
            int addAfterCount = response.count();
            // 没有下一页
            if (addBeforeCount == addAfterCount) {
                break;
            }

            // 获取本批次最大更新时间
            pageCondition = response.maxUpdateTime();

        }
        return response;
    }

    @Override
    public ShopOrderResponse pullShopAllOrders( String shopUrl, String accessToken, String updatedAtMin ) {

        ShopOrderResponse response = ShopOrderResponse.emptyResponse();
        String pageCondition = updatedAtMin;
        int limit = 200;

        while(true) {

            ShopOrderResponse orderPage = orderClient.listAfterUpdateAtOrders(accessToken,
                    shopUrl, ShopOrderResponse.FIELDS, pageCondition, limit).getResult();
            log.info("pullShopAllOrders orderPage: {}", QtFastjsonUtil.toJSONString(orderPage));
            if (!orderPage.success()) {
                break;
            }

            List<ShopOrderResponse.Orders> orders = orderPage.getOrders();
            int addBeforeCount = response.count();
            response.addAll(orders);
            int addAfterCount = response.count();
            // 没有下一页
            if (orderPage.count() < limit || addBeforeCount == addAfterCount) {
                log.info("pullShopAllOrders is last Page >>>>> ");
                break;
            }

            // 获取本批次最大更新时间
            pageCondition = response.maxUpdateTime();

        }
        return response;
    }

    @Override
    public ShopOrderResponse getOrderLatestUpdateTime( String shopUrl, String accessToken, List<Long> orderIds ) {
        if (CollUtil.isEmpty(orderIds)) {
            ShopOrderResponse.emptyResponse();
        }

        String ids = StringUtils.join(orderIds, StringPool.COMMA);
        ShopOrderResponse result = orderClient.listOrderLatestUpdateAtByIds(accessToken,
                shopUrl,
                ShopOrderResponse.IDS_FIELDS, ids).getResult();

        QtStreamUtil.peek(result.getOrders(),
                order -> order.setUpdatedTime(OffSetDateTimeUtil.convertISO8601ToUTCDateTime(order.getUpdatedAt())));

        return result;
    }

    @Override
    public ShopShippingNameResponse getShopShippingName( String shopUrl, String accessToken ) {
        ForestResponse<ShopShippingNameResponse> shopShippingNameResponseForestResponse = shopClient.shippingZones(accessToken, shopUrl);
        ShopShippingNameResponse result = shopShippingNameResponseForestResponse.getResult();
        return result;
    }

    private ShopifyCountResponse getOrderCount( String shopUrl, String accessToken, String updatedAtMin ) {
        if (StringUtils.isBlank(updatedAtMin)) {
            return orderClient.getOrderCount(accessToken, shopUrl).getResult();
        }
        return orderClient.getAfterUpdateAtOrderCount(accessToken, shopUrl, updatedAtMin).getResult();
    }

    @Override
    public FulfillmentOrderResponse fulfillmentOrders( String shopUrl, String accessToken, String orderId ) {
        ForestResponse<FulfillmentOrderResponse> fulfillmentOrderResponseForestResponse = orderClient.fulfillmentOrders(accessToken, shopUrl, orderId);
        FulfillmentOrderResponse result = fulfillmentOrderResponseForestResponse.getResult();
        return result;
    }

    @Override
    public FulfillmentResponse fulfillments( String shopUrl, String accessToken, FulfillmentRequest request ) {
        ForestResponse<FulfillmentResponse> fulfillmentResponseForestResponse = orderClient.fulfillments(accessToken, shopUrl, request);
        FulfillmentResponse result = fulfillmentResponseForestResponse.getResult();
        return result;
    }
}
